package model
{
    import flash.display.*;
    import flash.events.*;
    import flash.geom.*;
    import flash.utils.*;

    public class Cell extends Sprite
    {
        public static var WIDTH:Number = 32;
        public static var HEIGHT:Number = 32;
        public static var SELECTED_CELL:Cell = null;
        public static var OVER_CELL:Cell = null;
        public static var LOCKED:Boolean = false;
        public static var TYPE_NUM:int = 5;
        public static var EMPTY:int = 8;
        public static var STONE:int = 5;
        public static var COLORS:Array = new Array(0xFF0000, 0xFFFF00,
                                                   0x00C0FF, 0x00FF00,
                                                   0xFF30A0, 0x000000,
                                                   0x60FFA0, 0xFFA000);

        public var col:int;
        public var row:int;
        public var posX:Number;
        public var posY:Number;
        public var type:int;
        public var selected:Boolean;
        public var overed:Boolean;
        public var erased:Boolean;
        public var swapCell:Cell;
        public var swapType:int;
        public var swapTimer:Timer;

        public function Cell(t:int, col:int, row:int, x:Number=0, y:Number=0)
        {
            type = t;
            swapType = t;
            selected = false;
            overed = false;
            erased = false;
            buttonMode = true;
            this.x = x;
            this.y = y;
            posX = x;
            posY = y;
            this.col = col;
            this.row = row;
            swapTimer = new Timer(30, 1);
            swapTimer.addEventListener(TimerEvent.TIMER, animateSwap);

            addEventListener(MouseEvent.MOUSE_OVER, mouseOver);
            addEventListener(MouseEvent.MOUSE_DOWN, mouseDown);
        }

        public function display():void
        {
            var fillType:String = GradientType.LINEAR;
            var color:uint = Cell.COLORS[type];
            var colors:Array = [0xFFFFFF, 0x000000];
            var alpha:Number;
            var alphas:Array = [1, 1];
            var ratios:Array = [0, 190];
            var matr:Matrix = new Matrix();
            matr.createGradientBox(17, 20, 10.1, -1, 0);
            var spreadMethod:String = SpreadMethod.REFLECT;
            graphics.clear();
            if(type == Cell.EMPTY)
            {
                graphics.lineStyle(1, 0x303030, 0);
                alpha = 0;
            }
            else if(selected)
            {
                graphics.lineStyle(2, 0x000000, 1);
                alpha = 1;
            }
            else if(overed)
            {
                graphics.lineStyle(10, Cell.COLORS[type], 0.3);
                alpha = 1;
            }
            else
            {
                graphics.lineStyle(1, 0x303030, 1);
                alpha = 0.75;
            }
            colors[1] = color;
            alphas[1] = alpha;
            if(type == Cell.EMPTY)
            {
                graphics.beginFill(color, 0);
            }
            else
            {
                graphics.beginGradientFill(GradientType.LINEAR,
                                           colors, alphas,
                                           ratios, matr,
                                           spreadMethod,
                                           InterpolationMethod.RGB, 0.75);
            }
            graphics.moveTo(Cell.WIDTH/2, Cell.HEIGHT/4);
            graphics.lineTo(0, Cell.HEIGHT/2);
            graphics.lineTo(-Cell.WIDTH/2, Cell.HEIGHT/4);
            graphics.lineTo(-Cell.WIDTH/2, -Cell.HEIGHT/4);
            graphics.lineTo(0, -Cell.HEIGHT/2);
            graphics.lineTo(Cell.WIDTH/2, -Cell.HEIGHT/4);
            graphics.endFill();

            /*if(type != Cell.EMPTY)
            {
                graphics.lineStyle(1, 0x303030, 1);
                graphics.beginFill(0xFFFFFF, 1);
                graphics.drawEllipse(-6, -8, 6, 12);
                graphics.drawEllipse(0, -8, 6, 12);
                graphics.endFill();
                var a:Number = mouseX;
                var b:Number = mouseY;
                var c:Number = Math.sqrt(a*a + b*b);
                var dx:Number = 2*a/c;
                var dy:Number = 2*b/c;
                graphics.lineStyle(0, 0x000000, 1);
                graphics.beginFill(0x000000, 1);
                graphics.drawCircle(dx-3, dy-2, 2);
                graphics.drawCircle(dx+3, dy-2, 2);
                graphics.endFill();
            }*/
            if(selected) mouseEnabled = false;
            else mouseEnabled = true;
        }

        public function translate(toX:Number, toY:Number, v:Number):Boolean
        {
            var dx:Number = toX - posX;
            var dy:Number = toY - posY;
            var l:Number = Math.sqrt(dx*dx + dy*dy);
            this.x += dx*v/l;
            this.y += dy*v/l;
            if(((posX - this.x)*(toX - this.x) +
                (posY - this.y)*(toY - this.y)) > 0)
            {
                this.x = toX;
                this.y = toY;
                return false;
            }
            return true;
        }

        public function move(cell:Cell):void
        {
            swapType = cell.type;
            swapCell = cell;
            swapTimer.start();
        }
        
        private function animateSwap(e:TimerEvent):void
        {
            swapTimer.stop();
            swapTimer.reset();
            if(this.translate(swapCell.posX, swapCell.posY, 4))
            {
                swapTimer.start();
            }
            else
            {
                trace(">> swap");
                visible = false;
                type = swapType;
                this.x = posX;
                this.y = posY;
                visible = true;
                trace("<< swap");
            }
        }

        private function mouseOver(e:MouseEvent):void
        {
            if(!Cell.LOCKED)
            {
                overed = true;
                Cell.OVER_CELL = this;
            }
        }

        private function mouseDown(e:MouseEvent):void
        {
            if(!Cell.LOCKED)
            {
                if(Cell.SELECTED_CELL != null)
                {
                    Cell.SELECTED_CELL.selected = false;
                }
                selected = true;
                Cell.SELECTED_CELL = this;
            }
        }
    }
}
